package com.jstyle.jclifexd.fragment;

import android.Manifest;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.jstyle.blesdk.Util.ResolveUtil;
import com.jstyle.blesdk.cmdenum.SendCmdState;
import com.jstyle.blesdk.constant.DeviceConst;
import com.jstyle.jclifexd.R;
import com.jstyle.jclifexd.activity.EcgLandscapeActivity;
import com.jstyle.jclifexd.activity.EcgReportActivity;
import com.jstyle.jclifexd.activity.MainActivity;
import com.jstyle.jclifexd.ble.BleManager;
import com.jstyle.jclifexd.ble.BleService;
import com.jstyle.jclifexd.daoManager.HealthDataDaoManager;
import com.jstyle.jclifexd.model.BleData;
import com.jstyle.jclifexd.model.HealthData;
import com.jstyle.jclifexd.utils.ChartDataUtil;
import com.jstyle.jclifexd.utils.DateUtil;
import com.jstyle.jclifexd.utils.ImageUtils;
import com.jstyle.jclifexd.utils.PermissionsUtil;
import com.jstyle.jclifexd.utils.RxBus;
import com.jstyle.jclifexd.utils.SchedulersTransformer;
import com.jstyle.jclifexd.utils.ScreenUtils;
import com.jstyle.jclifexd.utils.SharedPreferenceUtils;
import com.neurosky.AlgoSdk.NskAlgoDataType;
import com.neurosky.AlgoSdk.NskAlgoECGValueType;
import com.neurosky.AlgoSdk.NskAlgoProfile;
import com.neurosky.AlgoSdk.NskAlgoSampleRate;
import com.neurosky.AlgoSdk.NskAlgoSdk;
import com.neurosky.AlgoSdk.NskAlgoType;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import lecho.lib.hellocharts.view.LineChartView;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link EcgFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class EcgFragment extends BaseFragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    @BindView(R.id.textView_ecg_hr)
    TextView textViewEcgHr;
    @BindView(R.id.textView_ecg_hrv)
    TextView textViewEcgHrv;


    @BindView(R.id.iv_change_display)
    ImageView ivChangeDisplay;
    @BindView(R.id.lineChartView_ppg)
    LineChartView lineChartViewPpg;
    @BindView(R.id.lineChartView_ecg)
    LineChartView lineChartViewEcg;
    Unbinder unbinder;
    @BindView(R.id.button_hrv_level)
    ImageView buttonHrvLevel;
    @BindView(R.id.button3)
    ImageView button3;


    @BindView(R.id.bt_startEcg)
    Button btStartEcg;
    @BindView(R.id.tv_ppg)
    TextView tvPpg;
    @BindView(R.id.tv_ecg)
    TextView tvEcg;
    int maxSize = 1536;
    int maxPpgSize = 600;
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;
    private Dialog tipsDialog;
    private NskAlgoSdk nskAlgoSdk;
    private Disposable subscription;
    private int currentSelectedAlgo;
    private int activeProfile = -1;
    private String filePath;
    private File fileOut;
    private FileOutputStream fileOutputStream;
    OutputStreamWriter outStream;
    public static final String ecgValueAction = "ecgValueAction";
    public static final String hrValueAction = "hrValueAction";
    public static final String hrvValueAction = "hrvValueAction";
    public static final String ppgValueAction = "ppgValueAction";

    public static final String ppgValue = "ppgValue";


    public EcgFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment EcgFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static EcgFragment newInstance(String param1, String param2) {
        EcgFragment fragment = new EcgFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    private static final String TAG = "EcgFragment";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        View view = inflater.inflate(R.layout.fragment_ecg, container, false);
        unbinder = ButterKnife.bind(this, view);
        if (!MainActivity.enterEcg && savedInstanceState == null) showTipsDialog();
        if (savedInstanceState != null) {
            isInitSdk = savedInstanceState.getBoolean(Key_InitSdk);

        }
        init(isInitSdk);
        subscribeEcg();


        return view;
    }

    private int index = 0;
    long saveTime = 0;

    private void createFile(List<Double> temp) {
        File ecgFile = new File(ImageUtils.ecgPath);
        if (!ecgFile.exists()) {
            ecgFile.mkdirs();
        }

        filePath = ImageUtils.ecgPath + DateUtil.getEcgFormatTimeString(saveTime) + ".ecg";
        fileOut = new File(filePath);
        try {
            if (!fileOut.exists()) {
                fileOut.createNewFile();
            }
            FileOutputStream fileOutputStream = new FileOutputStream(filePath);
            outStream = new OutputStreamWriter(fileOutputStream);
            StringBuffer stringBuffer = new StringBuffer();
            for (Double i : temp) {
                stringBuffer.append(String.valueOf(i) + ",");
            }
            outStream.write(stringBuffer.toString());
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            Log.i(TAG, "createFile: " + e.getMessage());
        } catch (Exception e) {
            Log.i(TAG, "createFile: " + e.getMessage());
        }
    }

    private void startSaveFile(final String date) {
        Log.i(TAG, "startSaveFile: ");
        final List<Double> temp = new ArrayList<>();
        temp.addAll(queueEcg);
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                createFile(temp);
                emitter.onComplete();
            }
        }).compose(SchedulersTransformer.io2MainObservable()).subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Object o) {

            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getMessage());
            }

            @Override
            public void onComplete() {
                Log.i(TAG, "onComplete: ");
                toEcgReportActivity(date);
            }
        });
    }

    int SignalQuality = 2;

    private void init(boolean enable) {

        nskAlgoSdk = new NskAlgoSdk();
        nskAlgoSdk.NskAlgoUninit();
        nskAlgoSdk.setOnSignalQualityListener(new NskAlgoSdk.OnSignalQualityListener() {
            @Override
            public void onSignalQuality(int i) {
                SignalQuality = i;
                Log.i(TAG, "onSignalQuality: " + i);
            }

            @Override
            public void onOverallSignalQuality(int i) {

            }
        });
        nskAlgoSdk.setOnECGAlgoIndexListener(new NskAlgoSdk.OnECGAlgoIndexListener() {
            @Override
            public void onECGAlgoIndex(int type, final int value) {

                switch (type) {
                    case NskAlgoECGValueType.NSK_ALGO_ECG_VALUE_TYPE_SMOOTH:
                        sendAction(ecgValueAction, String.valueOf(value));
                        queueEcg.add((double) value);
                        int size = queueEcg.size();
                        if (size >= 1536) {
                            index++;
                        }
                        if (size % 79 == 0) {
                            setLineChartViewEcgValue();
                        }
                        break;
                    case NskAlgoECGValueType.NSK_ALGO_ECG_VALUE_TYPE_ROBUST_HR:
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (SignalQuality < 3) return;
//                                if(value>0){
//                                    textViewEcgHr.setText(String.valueOf(value));
//                                    sendAction(hrValueAction, String.valueOf(value));
//                                }

                            }
                        });

                        break;
                    case NskAlgoECGValueType.NSK_ALGO_ECG_VALUE_TYPE_HRV:
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
//                                if(SignalQuality<3)return;
//                                textViewEcgHrv.setText(String.valueOf(value));
//                                sendAction(hrvValueAction, String.valueOf(value));
                            }
                        });

                        break;
                }
            }
        });

        loadsetup();
        setAlgos();
        initLineChartView();
        lineChartViewEcg.setLineChartData(ChartDataUtil.getEcgLineChartData(getActivity(), queueEcg, Color.RED, 4, index));
        if (MainActivity.enterEcg) {
            changeChartVisibility(true);
        }
        isInitSdk = true;
        // sendData(SendCmdState.READ_VERSION);
    }

    private void sendAction(String action, String value) {
        RxBus rxBus = RxBus.getInstance();
        BleData bleData = new BleData();
        bleData.setAction(action);
        bleData.setData(value);
        rxBus.post(bleData);
    }


    private void setAlgos() {

        Log.i(TAG, "setAlgos: " + license);
        String path = getActivity().getFilesDir().getAbsolutePath();
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_HRVFD;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_HRVTD;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_HRV;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_SMOOTH;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_HEARTAGE;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_HEARTRATE;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_MOOD;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_RESPIRATORY;
        currentSelectedAlgo |= NskAlgoType.NSK_ALGO_TYPE_ECG_STRESS;
        int ret = nskAlgoSdk.NskAlgoInit(currentSelectedAlgo, path, license);
        if (ret == 0) {
            Log.i(TAG, "setAlgos: Algo SDK has been initialized successfully");
        } else {
            Log.i(TAG, "Failed to initialize the SDK, code = " + String.valueOf(ret));
            return;
        }
        boolean b = nskAlgoSdk.setBaudRate(NskAlgoDataType.NSK_ALGO_DATA_TYPE_ECG, NskAlgoSampleRate.NSK_ALGO_SAMPLE_RATE_512);
        if (b != true) {
            Log.i(TAG, "setAlgos: Failed to set the sampling rate");
            return;
        }
        NskAlgoProfile[] profiles = nskAlgoSdk.NskAlgoProfiles();
        if (profiles.length == 0) {
            // create a default profile
            try {
                String dobStr = "1995-1-1";
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                Date dob = df.parse(dobStr);

                NskAlgoProfile profile = new NskAlgoProfile();
                profile.name = "bob";
                profile.height = 170;
                profile.weight = 80;
                profile.gender = false;
                profile.dob = dob;
                if (nskAlgoSdk.NskAlgoProfileUpdate(profile) == false) {
                    Log.d(TAG, "fail to setup the profile");
                }

                profiles = nskAlgoSdk.NskAlgoProfiles();
                // setup the ECG config
                // assert(nskAlgoSdk.NskAlgoSetECGConfigAfib((float)3.5) == true);
                assert (nskAlgoSdk.NskAlgoSetECGConfigStress(30, 30) == true);
                assert (nskAlgoSdk.NskAlgoSetECGConfigHeartage(30) == true);
                assert (nskAlgoSdk.NskAlgoSetECGConfigHRV(30) == true);
                assert (nskAlgoSdk.NskAlgoSetECGConfigHRVTD(30, 30) == true);
                assert (nskAlgoSdk.NskAlgoSetECGConfigHRVFD(30, 30) == true);

                // nskAlgoSdk.setSignalQualityWatchDog((short)20, (short)5);
                // retrieve the baseline data
                if (profiles.length > 0) {
                    activeProfile = profiles[0].userId;
                    nskAlgoSdk.NskAlgoProfileActive(activeProfile);
                    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
                    String stringArray = settings.getString("ecgbaseline", null);
                    if (stringArray != null) {
                        String[] split = stringArray.substring(1, stringArray.length() - 1).split(", ");
                        byte[] array = new byte[split.length];
                        for (int i = 0; i < split.length; ++i) {
                            array[i] = Byte.parseByte(split[i]);
                        }
                        if (nskAlgoSdk.NskAlgoProfileSetBaseline(activeProfile, NskAlgoType.NSK_ALGO_TYPE_ECG_HEARTRATE, array) != true) {
                            Log.d(TAG, "error in setting the profile baseline");
                        }
                    }
                }

            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

    }

    private void initLineChartView() {
        ChartDataUtil.initDataChartView(lineChartViewEcg, 0, 8000, maxSize, -8000);
    }

    private void initPPgView(double top, double bottom) {
        //ChartDataUtil.initDataChartView(lineChartViewPpg, 0, 10000, maxSize, -10000);
        //setLineChartViewPpgValue(top, bottom);
    }

    List<Double> queueEcg = new ArrayList<>();
    List<Integer> fileEcgList = new ArrayList<>();
    List<Float> queuePpg = new ArrayList<>();

    private void setLineChartViewEcgValue() {
        if (isDraw) {
            final int tempCount = index;
            lineChartViewEcg.setLineChartData(ChartDataUtil.getEcgLineChartData(getActivity(), queueEcg, Color.RED, 4, tempCount));
        }
    }

    double maxPPG = 0;
    double minPPg = 33000;

    private void setLineChartViewPpgValue(double top, double bottom) {

        if (isDraw) {
            lineChartViewPpg.setLineChartData(ChartDataUtil.getPpgChartData(lineChartViewPpg,getActivity(), queuePpg, Color.RED));

         //   lineChartViewPpg.setLineChartData(ChartDataUtil.getPpgLineChartData(getActivity(), queuePpg, Color.RED));

        }
    }

    protected void subscribeEcg() {
        subscription = RxBus.getInstance().toObservable(BleData.class).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<BleData>() {
            @Override
            public void accept(BleData bleData) throws Exception {
                String action = bleData.getAction();
                if (action.equals(BleService.ACTION_DATA_AVAILABLE)) {
                    Log.i(TAG, "accept: " + Thread.currentThread().getId());
                    byte[] value = bleData.getValue();
                    resolveData(value);
                }

            }
        });
    }

    int versionCode;
    int raw_data_index = 0;
    //    double maxPPG = 0;
//    double minPPg = 33000;
    List<Double> integerList = new ArrayList<>();
    int avgIndex = 4;

    private void resolveData(byte[] value) {

        switch (value[0]) {
            case DeviceConst.CMD_ECGQuality:
                int heartValue = ResolveUtil.getValue(value[1], 0);
                int hrvValue = ResolveUtil.getValue(value[2], 0);
                int Quality = ResolveUtil.getValue(value[3], 0);
                if (Quality >= 0) {
                    if (heartValue > 0) {
                        textViewEcgHr.setText(String.valueOf(heartValue));
                        sendAction(hrValueAction, String.valueOf(heartValue));
                    }
                    if (hrvValue > 0) {
                        textViewEcgHrv.setText(String.valueOf(hrvValue));
                        sendAction(hrvValueAction, String.valueOf(hrvValue));
                    }

                }
                break;
            case DeviceConst.CMD_ECGDATA:
                // Log.i(TAG, "resolveData: "+ ResolveData.byte2Hex(value));
//
//                    for (int i = 0; i < value.length / 2 - 1; i++) {
//                        int ecgValue = ResolveUtil.getValue(value[i * 2 + 1], 1) + ResolveUtil.getValue(value[i * 2 + 2], 0);
//                        if (ecgValue >= 32768) ecgValue = ecgValue - 65536;
//                     //   integerList.add((double) ecgValueAction);
//                        double data=ResolveData.getSleepQData(ecgValue);
//                        sendAction(ecgValueAction, String.valueOf(data));
//                        queueEcg.add( data);
//                        int size=queueEcg.size();
//                        if(size>=1536){
//                            index++;
//                        }
//                        if(size%79==0){
//                            setLineChartViewEcgValue();
//                        }
//                    }
                // sendAction(ecgValueAction, String.valueOf(value));
//                }else{
                if (raw_data_index == 0 || raw_data_index % 200 == 0) {
                    // send the good signal for every half second
                    short pqValue[] = {(short) 200};
                    nskAlgoSdk.NskAlgoDataStream(NskAlgoDataType.NSK_ALGO_DATA_TYPE_ECG_PQ, pqValue, 1);
                }
                for (int i = 0; i < value.length / 2 - 1; i++) {
                    int ecgValueAction = ResolveUtil.getValue(value[i * 2 + 1], 1) + ResolveUtil.getValue(value[i * 2 + 2], 0);
                    if (ecgValueAction >= 32768) ecgValueAction = ecgValueAction - 65536;
                    raw_data_index++;
                    short[] ecgData = new short[]{(short) -ecgValueAction};
                    nskAlgoSdk.NskAlgoDataStream(NskAlgoDataType.NSK_ALGO_DATA_TYPE_ECG, ecgData, 1);
                }


                break;
            case DeviceConst.CMD_PPGGDATA:
                double maxPPG = 0;
                double minPPg = 33000;
                for (int i = 0; i < value.length / 2 - 1; i++) {
                 //   float ppgValue = ChartDataUtil.getPPgData(ResolveUtil.getValue(value[i * 2 + 1], 1) + ResolveUtil.getValue(value[i * 2 + 2], 0));
                    float ppgValue = ResolveUtil.getValue(value[i * 2 + 1], 1) + ResolveUtil.getValue(value[i * 2 + 2], 0);
                    if (ppgValue >= 32768) ppgValue = ppgValue - 65536;
                //    if (ppgValue >= 32768) ppgValue = ppgValue - 65536;
                    if (queuePpg.size() > maxPpgSize) queuePpg.remove(0);
                    queuePpg.add(ppgValue);
                    sendAction(ppgValueAction, String.valueOf(ppgValue));
                    maxPPG = Math.max(maxPPG, ppgValue);
                    minPPg = Math.min(minPPg, ppgValue);
                }
                initPPgView(maxPPG, minPPg);
                break;
            case DeviceConst.CMD_Result_ECGPPG:
                if (value[1] == (byte) 0x0c) {
                    clearEcgPPgDatas();
                    return;
                }
                if (value[1] != (byte) 0xff && value[1] != 0x01 && value[1] != (byte) 0x0b) {
                    if (value[1] == 3) {
                        saveTime = System.currentTimeMillis();
                        String address = SharedPreferenceUtils.getSpString(SharedPreferenceUtils.KEY_ADDRESS);
                        HealthData healthData = new HealthData();
                        String date = ResolveUtil.bcd2String(value[10]) + "."
                                + ResolveUtil.bcd2String(value[11]) + "." + ResolveUtil.bcd2String(value[12]) + " "
                                + ResolveUtil.bcd2String(value[13]) + ":" + ResolveUtil.bcd2String(value[14]) + ":" + ResolveUtil.bcd2String(value[15]);
                        int hrv = ResolveUtil.getValue(value[2], 0);
                        int avBlock = ResolveUtil.getValue(value[3], 0);
                        int hr = ResolveUtil.getValue(value[4], 0);
                        int strees = ResolveUtil.getValue(value[5], 0);
                        int highBp = ResolveUtil.getValue(value[6], 0);
                        int lowBp = ResolveUtil.getValue(value[7], 0);
                        int moodValue = ResolveUtil.getValue(value[8], 0);
                        int breathValue = ResolveUtil.getValue(value[9], 0);
                        healthData.setAddress(address);
                        healthData.setTime(date);
                        healthData.setLowBloodPressure(lowBp);
                        healthData.setHighBloodPressure(highBp);
                        healthData.setHrv(hrv);
                        healthData.setHeartRate(hr);
                        healthData.setBloodValue(avBlock);
                        healthData.setPressure(strees);
                        healthData.setMoodValue(moodValue);
                        healthData.setBreathValue(breathValue);
                        healthData.setFileName(saveTime);
                        HealthDataDaoManager.insertData(healthData);
                        startSaveFile(date);

                    }
                    changeChartVisibility(false);

                }
                break;
            case DeviceConst.CMD_Get_Version:
                String version = ResolveUtil.getDeviceVersion(value);
                versionCode = Integer.parseInt(version.replace(".", ""));

                break;
        }
    }

    private void toEcgReportActivity(String date) {

        Intent intent = new Intent(getActivity(), EcgReportActivity.class);
        intent.putExtra(EcgReportActivity.ECGPATH, filePath);
        intent.putExtra(EcgReportActivity.ECGDATE, date);
        startActivity(intent);
    }

    private short[] byteArray2ShortArray(byte[] data) {
        short[] retVal = new short[data.length / 2];
        for (int i = 0; i < retVal.length; i++)
            retVal[i] = (short) ((data[i * 2] & 0xff) << 8 | (data[i * 2 + 1] & 0xff));
//        short[] shorts = new short[data.length/2];
//       ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
        return retVal;
    }

    private String license = "";

    private void loadsetup() {
        AssetManager assetManager = getActivity().getAssets();
        InputStream inputStream = null;

        try {
            String prefix = "license key=\"";
            String suffix = "\"";
            String pattern = prefix + "(.+?)" + suffix;
            Pattern p = Pattern.compile(pattern);

            inputStream = assetManager.open("license.txt");
            ArrayList<String> data = new ArrayList<String>();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                while (true) {
                    String line = reader.readLine();
                    if (line == null || line.isEmpty())
                        break;
                    Matcher m = p.matcher(line);
                    if (m.find()) {
                        license = line.substring(m.regionStart() + prefix.length(), m.regionEnd() - suffix.length());
                        break;
                    }
                }
            } catch (IOException e) {

            }
            inputStream.close();
        } catch (IOException e) {
            Log.e(TAG, "Cant load the license file");
        }

        try {
            inputStream = assetManager.open("setupinfo.txt");
            ArrayList<String> data = new ArrayList<String>();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                while (true) {
                    String line = reader.readLine();
                    if (line == null || line.isEmpty()) {
                        break;
                    }
                    data.add(line);
                }
            } catch (IOException e) {

            }
            inputStream.close();
//
//            for (int i = 0; i < data.size(); ++i) {
//                enableCheckBox(data.get(i));
//            }

        } catch (IOException e) {
            Log.e(TAG, "Cant load the setup file");
        }

        Log.d(TAG, "Finished reading data");
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

    }

    private void showTipsDialog() {
        if (tipsDialog == null) {
            tipsDialog = new Dialog(getActivity());
            tipsDialog.setContentView(R.layout.dialog_startecg_tips);
            tipsDialog.findViewById(R.id.bt_startecg_ok).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    tipsDialog.dismiss();
                }
            });
            tipsDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            ViewGroup.LayoutParams lay = tipsDialog.getWindow().getAttributes();
            lay.width = ScreenUtils.getScreenWidth(getActivity());
        }
        tipsDialog.show();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
        unSubscribe(subscription);
        Log.i(TAG, "onDestroyView: ");
    }

    boolean isDraw;

    @Override
    public void onResume() {
        super.onResume();
        isDraw = true;
    }

    @Override
    public void onPause() {
        super.onPause();
        isDraw = false;
    }

    @OnClick({R.id.iv_change_display, R.id.bt_startEcg})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.iv_change_display:
                switchToLandscape();
                break;
            case R.id.bt_startEcg:
                PermissionsUtil.requestPermissions((MainActivity) getActivity(), new PermissionsUtil.PermissionListener() {
                    @Override
                    public void granted(String name) {
                        startMeasure();
                        // createFile();
                    }

                    @Override
                    public void NeverAskAgain() {

                    }

                    @Override
                    public void disallow(String name) {

                    }
                }, Manifest.permission.WRITE_EXTERNAL_STORAGE);

                break;
        }

    }

    private void createFileAndInitSdk() {
        //setAlgos();
        //createFile();
        //startEcgTimer();
        nskAlgoSdk.NskAlgoStart(false);
    }

    private void startMeasure() {
        if (BleManager.getInstance().isConnected()) {
            changeChartVisibility(true);
            sendData(SendCmdState.ENABLE_ECGPPG);

        }
    }

    public void changeChartVisibility(boolean start) {
        if (!isAdded()) return;
        if (!start) {
            unSubscribe(ppgDisposable);
            clearEcgPPgDatas();
            nskAlgoSdk.NskAlgoStop();
        } else {
            startPPGTimer();
            createFileAndInitSdk();
        }
        tvEcg.setVisibility(start ? View.VISIBLE : View.INVISIBLE);
        tvPpg.setVisibility(start ? View.VISIBLE : View.INVISIBLE);
        ivChangeDisplay.setVisibility(start ? View.VISIBLE : View.INVISIBLE);
        lineChartViewEcg.setVisibility(start ? View.VISIBLE : View.INVISIBLE);
        lineChartViewPpg.setVisibility(start ? View.VISIBLE : View.INVISIBLE);
        btStartEcg.setVisibility(start ? View.INVISIBLE : View.VISIBLE);
        MainActivity.enterEcg = false;
    }

    private void clearEcgPPgDatas() {

        index = 0;
        avgIndex = 4;
        fileEcgList.clear();
        queuePpg.clear();
        queueEcg.clear();
        integerList.clear();
        setLineChartViewPpgValue(8000, -8000);
        setLineChartViewEcgValue();
        textViewEcgHrv.setText("--");
        textViewEcgHr.setText("--");

    }

    private void switchToLandscape() {
        startActivity(EcgLandscapeActivity.class);
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }

    boolean isInitSdk;
    private static final String Key_InitSdk = "Key_InitSdk";

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(Key_InitSdk, isInitSdk);
        Log.i(TAG, "onSaveInstanceState: ");
    }
    Disposable ppgDisposable;
    private void startPPGTimer(){
        if(ppgDisposable!=null&&!ppgDisposable.isDisposed())return;
        Observable.interval(100, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Long>() {
            @Override
            public void onSubscribe(Disposable d) {
                ppgDisposable=d;
            }

            @Override
            public void onNext(Long aLong) {
                setLineChartViewPpgValue(0,0);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }
}
